import {
    isUndef,
    isDef,
    isPrimitive,
    isTrue
} from '../util/index'
import VNode from './vnode'
export function createPatchFunction(backend) {
    let { nodeOps, modules } = backend;
    function createComponent(vnode, insertedVnodeQueue, parentElm, refElm) {
        let i = vnode.data
        if (isDef(i)) {
            if (isDef(i = i.hook) && isDef(i = i.init)) {
                //创建组件调用初始化init函数
                console.log('创建组件调用初始化init函数')
                i(vnode, false)
            }
        }
        if (isDef(vnode.componentInstance)) {
            initComponent(vnode, insertedVnodeQueue)
            //渲染组件的元素
            console.log('渲染组件的元素',parentElm,vnode.elm)
            insert(parentElm, vnode.elm, refElm)
            return true
        }

    }
    function insert (parent, elm, ref) {
        if (isDef(parent)) {
            if (isDef(ref)) {
                if (nodeOps.parentNode(ref) === parent) {
                  nodeOps.insertBefore(parent, elm, ref)
                }
            } else {
                console.log('压入元素'+ parentElm + '压入',vnode.elm)
                nodeOps.appendChild(parent, elm)
            }
        } else {
            //组件没有parent 直接返回
            console.log('组件没有parent 直接返回')
        }
    }
    function initComponent(vnode, insertedVnodeQueue) {
        if (isDef(vnode.data.pendingInsert)) {

        }
        vnode.elm = vnode.componentInstance.$el;
        if (isPatchable(vnode)) {

        } else {
            insertedVnodeQueue.push(vnode)
        }
    }
    function isPatchable (vnode) {
        while (vnode.componentInstance) {
          vnode = vnode.componentInstance._vnode
        }
        return isDef(vnode.tag)
    }
    function createElm(vnode, insertedVnodeQueue, parentElm, refElm) {
        if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) {
            return
        }
        const data = vnode.data;
        const children = vnode.children;
        const tag = vnode.tag;
        if (isDef(tag)) {
            //创建元素
            vnode.elm = nodeOps.createElement(tag);
            console.log('创建元素',vnode.elm)
            //递归渲染子级
            createChildren(vnode, children, insertedVnodeQueue)
            insert(parentElm, vnode.elm, refElm)
        } else if (isTrue(vnode.isComment)) {
            vnode.elm = nodeOps.createComment(vnode.text)
            insert(parentElm, vnode.elm, refElm)
        }else {
            vnode.elm = nodeOps.createTextNode(vnode.text)
            insert(parentElm, vnode.elm, refElm)
        }
    };
    function createChildren (vnode, children, insertedVnodeQueue) {
        if (Array.isArray(children)) {
            for (let i = 0; i < children.length; ++i) {
            //递归渲染子级
            createElm(children[i], insertedVnodeQueue, vnode.elm)
          }
        } else if (isPrimitive(vnode.text)) {
        //   nodeOps.appendChild(vnode.elm, nodeOps.createTextNode(String(vnode.text)))
        }
    }
    function emptyNodeAt(elm) {
        return new VNode(nodeOps.tagName(elm).toLowerCase(), {}, [], undefined, elm)
    }
    return function patch(oldVnode, vnode, hydrating, removeOnly) {
        let isInitialPatch = false
        const insertedVnodeQueue = []
        if (isUndef(oldVnode)) {
            console.log('组件渲染走这里',vnode)
            //空挂载(可能作为组件)，创建新的根元素
            isInitialPatch = true;
            createElm(vnode, insertedVnodeQueue);
        } else {
            console.log('普通渲染走这里')
            //检查oldVnode.nodeType是否是真实dom
            const isRealElement = isDef(oldVnode.nodeType);
            if (isRealElement) {
                //利用传进来的el 转换成VNode
                oldVnode = emptyNodeAt(oldVnode)
            }
            const oldElm = oldVnode.elm;
            //获取父节点，也就是body
            const parentElm = nodeOps.parentNode(oldElm);
            //创建元素
            createElm(
                vnode,
                insertedVnodeQueue,
                parentElm,
                nodeOps.nextSibling(oldElm)
            )
        }
        return vnode.elm
    }
}